using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using DatabaseManager.UI;
using System.Drawing;
using System.Data;

namespace DatabaseManager.Util
{
    /// <summary>
    /// Some general utility functions for this projects, which can be used anywhere in the project
    /// </summary>
    public static class Utility
    {
        /// <summary>
        /// Moving direction for selected ListView entries
        /// </summary>
        public enum Direction
        {
            /// <summary>
            /// Move ListView entries upwards.
            /// </summary>
            Up,
            /// <summary>
            /// Move ListView entries downwards.
            /// </summary>
            Down
        }

        /// <summary>
        /// Determines if the given class type implements the given interface.
        /// </summary>
        /// <param name="classType">Type of the class.</param>
        /// <param name="interfaceType">Type of the interface.</param>
        /// <returns></returns>
        public static bool ClassContainsInterface(Type classType, Type interfaceType)
        {
            Type pluginInterface = classType.GetInterface(interfaceType.FullName);

            return (pluginInterface != null);
        }

        /// <summary>
        /// Gets the file name of the help file (combination of Application.Path and "DatabaseManager.chm").
        /// </summary>
        /// <returns></returns>
        public static string GetHelpFileName()
        {
            return Path.Combine(
                Application.StartupPath,
                "DatabaseManager.chm");
        }

        /// <summary>
        /// Move a the selected items in a ListView box in a specified direction.
        /// </summary>
        /// <param name="listView">The ListView.</param>
        /// <param name="direction">The direction.</param>
        public static void MoveListViewItems(ListView listView, Direction direction)
        {
            List<ListViewItem> selectedItems = new List<ListViewItem>();

            foreach (ListViewItem lvItem in listView.SelectedItems)
            {
                selectedItems.Add(lvItem);
            }

            MoveListViewItems(listView, selectedItems, direction);
        }

        /// <summary>
        /// Move a given list of ListView entries in a ListView box in a specified direction.
        /// </summary>
        /// <param name="listView">The ListView.</param>
        /// <param name="listViewItems">The ListView items, which will be moved.</param>
        /// <param name="direction">The direction.</param>
        public static void MoveListViewItems(ListView listView, IEnumerable<ListViewItem> listViewItems, Direction direction)
        {
            List<ListViewItem> items = new List<ListViewItem>(listViewItems);
            if (direction == Direction.Down)
            {
                for (int i = items.Count - 1; i >= 0 ; i--)
			    {
                    ListViewItem lvItem = items[i];

                    int oldIndex = lvItem.Index;
                    int newIndex;

                    listView.Items.Remove(lvItem);

    			    if (oldIndex == listView.Items.Count)
                    {
                        newIndex = 0;
                    }
                    else
                    {
                        newIndex = oldIndex + 1;
                    } 

                    listView.Items.Insert(newIndex, lvItem);
			    }
            }
            else
            {
                foreach (ListViewItem lvItem in items)
                {
                    int oldIndex = lvItem.Index;
                    int newIndex;

                    listView.Items.Remove(lvItem);

                    if (oldIndex == 0)
                    {
                        newIndex = listView.Items.Count;
                    }
                    else
                    {
                        newIndex = oldIndex - 1;
                    }

                    listView.Items.Insert(newIndex, lvItem);
                }
            }
        }

        /// <summary>
        /// Gets the absolute path from a root path combined with a relative path part or if the relativePathPart parameter is already rooted only this one.
        /// </summary>
        /// <param name="rootPath">The root path.</param>
        /// <param name="relativePathPart">The relative path part or the absolute path.</param>
        /// <returns></returns>
        public static string GetRealAbsolutePath(string rootPath, string relativePathPart)
        {
            string realAbsolutePath;

            if (Path.IsPathRooted(relativePathPart))
            {
                realAbsolutePath = relativePathPart;
            }
            else
            {
                realAbsolutePath = Path.Combine(rootPath, relativePathPart);
            }

            return realAbsolutePath;
        }

        /// <summary>
        /// Shows the exception box.
        /// </summary>
        /// <param name="occuredException">The occured exception.</param>
        /// <param name="title">The title of the message box.</param>
        public static void ShowExceptionBox(Exception occuredException, string title)
        {
            ShowExceptionBox(occuredException, title, null, null);
        }

        /// <summary>
        /// Shows the exception box.
        /// </summary>
        /// <param name="occuredException">The occured exception.</param>
        public static void ShowExceptionBox(Exception occuredException)
        {
            ShowExceptionBox(occuredException, null);
        }

        /// <summary>
        /// Shows the exception box.
        /// </summary>
        /// <param name="occuredException">The occured exception.</param>
        /// <param name="title">The title of the message box.</param>
        /// <param name="prefixErrorText">Some text before the error message of the occured exception.</param>
        /// <param name="postfixErrorText">Some text after the error message of the occured exception.</param>
        public static void ShowExceptionBox(Exception occuredException, string title, string prefixErrorText, string postfixErrorText)
        { 
            /*
            if(!string.IsNullOrEmpty(prefixErrorText))
            {
                prefixErrorText += Environment.NewLine + Environment.NewLine;
            }

            if(!string.IsNullOrEmpty(postfixErrorText))
            {
                postfixErrorText = Environment.NewLine + Environment.NewLine + postfixErrorText;
            }

            if(string.IsNullOrEmpty(title))
            {
                title = "Fehler";
            }

            MessageBox.Show(
                prefixErrorText +
                occuredException.Message +
                postfixErrorText,
                title,
                MessageBoxButtons.OK,
                MessageBoxIcon.Error);
            */

            FExceptionDialog exceptionDialog = new FExceptionDialog(occuredException, title, prefixErrorText, postfixErrorText);
            exceptionDialog.ShowDialog();
        }

        /// <summary>
        /// Sets automatically the width of the DropDown list of a ComboBox.
        /// </summary>
        /// <param name="comboBox">The ComboBox.</param>
        public static void SetAutoDropDownWidth(ComboBox comboBox)
        {
            /*
             * found from
             * http://weblogs.asp.net/eporter/archive/2004/09/27/234773.aspx
             */

            bool isDatabound = comboBox.DataSource != null && comboBox.DisplayMember != null && comboBox.DisplayMember != "";
            int widestWidth = comboBox.DropDownWidth;
            string valueToMeasure;
            int currentWidth;

            using (Graphics g = comboBox.CreateGraphics())
            {
                for (int i = 0; i < comboBox.Items.Count; i++)
                {
                    if (isDatabound)
                        valueToMeasure = (string)((DataRowView)comboBox.Items[i])[comboBox.DisplayMember];
                    else
                        valueToMeasure = (string)comboBox.Items[i];

                    currentWidth = (int)g.MeasureString(valueToMeasure, comboBox.Font).Width;
                    if (currentWidth > widestWidth) { widestWidth = currentWidth; }
                }
            }

            comboBox.DropDownWidth = widestWidth;
        }
    }
}
